home *** CD-ROM | disk | FTP | other *** search
/ MACD 5 / MACD 5.bin / workbench / libs / intuisup.lha / Intuisup / source.lha / Editor / template.c < prev    next >
C/C++ Source or Header  |  1992-10-02  |  21KB  |  870 lines

  1. /* $Revision Header *** Header built automatically - do not edit! ***********
  2.  *
  3.  *    (C) Copyright 1991 by Torsten Jürgeleit
  4.  *
  5.  *    Name .....: template.c
  6.  *    Created ..: Sunday 22-Dec-91 21:23:14
  7.  *    Revision .: 1
  8.  *
  9.  *    Date        Author                 Comment
  10.  *    =========   ====================   ====================
  11.  *    02-Oct-92   Michael Bjerking       New realese, better Screen/Window editor
  12.  *    31-Dec-91   Torsten Jürgeleit      new font management
  13.  *    22-Dec-91   Torsten Jürgeleit      Created this file!
  14.  *
  15.  ****************************************************************************
  16.  *
  17.  *    Template part
  18.  *
  19.  * $Revision Header ********************************************************/
  20.  
  21.  /* Includes */
  22.  
  23. #include "includes.h"
  24. #include "defines.h"
  25. #include "imports.h"
  26. #include "protos.h"
  27.  
  28.  /* Get current template by given ordinal number from list */
  29.  
  30. struct Template *
  31. get_template_by_num(LONG num)
  32. {
  33.     struct Template *tp;
  34.  
  35.     for (tp = get_head((struct List *) & template_list.tl_Templates); tp; tp = get_succ(&tp->tp_Node))
  36.     {
  37.         if (!num--)
  38.         {
  39.             CopyMem((BYTE *) & tp->tp_Box, (BYTE *) & current_box, (LONG) sizeof(struct Box));
  40.             break;
  41.         }
  42.     }
  43.  
  44.     selected_template = tp;
  45.     return (tp);
  46. }
  47.  
  48.  /* Get current template by given mouse pos from list */
  49.  
  50. struct Template *
  51. get_template_by_pos(SHORT x, SHORT y)
  52. {
  53.     struct Template *tp;
  54.  
  55.     if (tp = find_template_by_pos(x, y))
  56.     {
  57.         CopyMem((BYTE *) & tp->tp_Box, (BYTE *) & current_box, (LONG)
  58.                 sizeof(struct Box));
  59.     }
  60.     selected_template = tp;
  61.     return (tp);
  62. }
  63.  
  64.  /* Find template by given mouse pos from list */
  65.  
  66. struct Template *
  67. find_template_by_pos(SHORT x, SHORT y)
  68. {
  69.     struct Template *tp;
  70.     struct Box *box;
  71.  
  72.     /* First check info template */
  73.     if (info_displayed == TRUE)
  74.     {
  75.         tp = info_template;
  76.         box = &tp->tp_Box;
  77.         if (x >= box->bo_X1 && x <= box->bo_X2 && y >= box->bo_Y1 && y <=
  78.             box->bo_Y2)
  79.         {
  80.             return (tp);
  81.         }
  82.     }
  83.  
  84.     /* Now check templates in list (from last to first) */
  85.     for (tp = get_tail((struct List *) & template_list.tl_Templates); tp;
  86.          tp = get_pred(&tp->tp_Node))
  87.     {
  88.         box = &tp->tp_Box;
  89.         if (x >= box->bo_X1 && x <= box->bo_X2 && y >= box->bo_Y1 && y <=
  90.             box->bo_Y2)
  91.         {
  92.             return (tp);
  93.         }
  94.     }
  95.     return (NULL);
  96. }
  97.  
  98.  /* Fix bounds of current template */
  99.  
  100. VOID
  101. fix_template_bounds(VOID)
  102. {
  103.     struct Box *box = ¤t_box;
  104.  
  105.     if (box->bo_X1 > box->bo_X2)
  106.     {
  107.         SHORT temp = box->bo_X2;
  108.  
  109.         box->bo_X2 = box->bo_X1;
  110.         box->bo_X1 = temp;
  111.     }
  112.     if (box->bo_Y1 > box->bo_Y2)
  113.     {
  114.         SHORT temp = box->bo_Y2;
  115.  
  116.         box->bo_Y2 = box->bo_Y1;
  117.         box->bo_Y1 = temp;
  118.     }
  119.     if (box->bo_X1 < 0)
  120.     {
  121.         box->bo_X1 = 0;
  122.     }
  123.     if (box->bo_Y1 < 0)
  124.     {
  125.         box->bo_Y1 = 0;
  126.     }
  127.     if (box->bo_X2 > pwin->Width)
  128.     {
  129.         box->bo_X2 = pwin->Width;
  130.     }
  131.     if (box->bo_Y2 > pwin->Height)
  132.     {
  133.         box->bo_Y2 = pwin->Height;
  134.     }
  135. }
  136.  
  137.  /* Get modify mode from selected position */
  138.  
  139. USHORT
  140. get_modify_mode(SHORT x, SHORT y)
  141. {
  142.     struct Template *tp = selected_template;
  143.     struct Box *box = &tp->tp_Box;
  144.     UBYTE type = tp->tp_Type;
  145.     USHORT part_width = (box->bo_X2 - box->bo_X1) / 8, part_height = (box->bo_Y2 - box->bo_Y1) / 4, modify_mode = MODIFY_MODE_MOVE;
  146.  
  147.     if (type != TEMPLATE_TYPE_TEXT && type != TEMPLATE_TYPE_CHECK &&
  148.         type != TEMPLATE_TYPE_MX)
  149.     {
  150.         if (x >= (box->bo_X2 - part_width) && x <= box->bo_X2 &&
  151.             y >= (box->bo_Y2 - part_height) && y <= box->bo_Y2)
  152.         {
  153.             modify_mode = MODIFY_MODE_RESIZE;
  154.         }
  155.     }
  156.     return (modify_mode);
  157. }
  158.  
  159.  /* Create new template and add it to template list */
  160.  
  161. struct Template *
  162. create_template(struct TemplateList *tl)
  163. {
  164.     struct Template *tp;
  165.     SHORT status = EDITOR_STATUS_NORMAL;
  166.  
  167.     if (!(tp = AllocMem((LONG) sizeof(struct Template),
  168.                          (LONG) MEMF_PUBLIC | MEMF_CLEAR)))
  169.     {
  170.         status = EDITOR_ERROR_OUT_OF_MEM;
  171.     }
  172.     else
  173.     {
  174.  
  175.         /* Init template */
  176.         tp->tp_Node.ln_Name = &tp->tp_TemplateName[0];
  177.         tp->tp_Type = template_type;
  178.         CopyMem((BYTE *) & current_box, (BYTE *) & tp->tp_Box, (LONG)
  179.                 sizeof(struct Box));
  180.         NewList(&tp->tp_TextList);
  181.         if ((status = init_default_template_data(tl, tp, FALSE)) !=
  182.             EDITOR_STATUS_NORMAL)
  183.         {
  184.             free_template(tl, tp);
  185.             tp = NULL;
  186.         }
  187.         else
  188.         {
  189.  
  190.             /* Add new template to list and refresh list view */
  191.             add_template_to_list(tl, tp, TRUE);
  192.             ISetGadgetAttributes(egl, EDITOR_GADGET_TEMPLATES, 0L, 0L,
  193.                                  USE_CURRENT_VALUE, USE_CURRENT_VALUE, &tl->tl_Templates);
  194.         }
  195.     }
  196.     show_error(status);
  197.     return (tp);
  198. }
  199.  
  200.  /* Add template to list */
  201.  
  202. VOID
  203. add_template_to_list(struct TemplateList * tl, struct Template * tp,
  204.                      BOOL default_name)
  205. {
  206.     struct List *list = (struct List *) & tl->tl_Templates;
  207.     USHORT num, pos;
  208.  
  209.     /* Get group data */
  210.     switch (TEMPLATE_GROUP(tp))
  211.     {
  212.     case TEMPLATE_GROUP_BORDER:
  213.         num = ++tl->tl_BorderTemplates;
  214.         pos = num - 1;
  215.         break;
  216.  
  217.     case TEMPLATE_GROUP_TEXT:
  218.         num = ++tl->tl_TextTemplates;
  219.         pos = tl->tl_BorderTemplates + num - 1;
  220.         break;
  221.  
  222.     case TEMPLATE_GROUP_GADGET:
  223.         num = ++tl->tl_GadgetTemplates;
  224.         pos = tl->tl_BorderTemplates + tl->tl_TextTemplates + num - 1;
  225.         break;
  226.     }
  227.  
  228.     /* Init template and insert it into template list */
  229.     tp->tp_GroupEntryNum = num;
  230.     if (default_name == TRUE)
  231.     {
  232.         build_default_template_name(tl, tp);
  233.     }
  234.     Insert(list, &tp->tp_Node, (pos ? get_node(list, pos - 1) : NULL));
  235. }
  236.  
  237.  /* Build default template name */
  238.  
  239. VOID
  240. build_default_template_name(struct TemplateList *tl, struct Template *tp)
  241. {
  242.     BYTE *fmt;
  243.  
  244.     switch (TEMPLATE_GROUP(tp))
  245.     {
  246.     case TEMPLATE_GROUP_BORDER:
  247.         fmt = "BORDER%d";
  248.         break;
  249.  
  250.     case TEMPLATE_GROUP_TEXT:
  251.         fmt = "TEXT%d";
  252.         break;
  253.  
  254.     case TEMPLATE_GROUP_GADGET:
  255.         fmt = "GADGET%d";
  256.         break;
  257.     }
  258.     sprintf(&tp->tp_TemplateName[0], fmt, tp->tp_GroupEntryNum);
  259.     tp->tp_Flags = TEMPLATE_FLAG_DEFAULT_NAME;
  260. }
  261.  
  262.  /* Init default template data */
  263.  
  264. SHORT
  265. init_default_template_data(struct TemplateList *tl, struct Template *tp,
  266.                            BOOL default_name)
  267. {
  268.     struct Box *box = &tp->tp_Box;
  269.     struct BorderData *bd;
  270.     struct TextData *td;
  271.     struct GadgetData *gd;
  272.     USHORT width = box->bo_X2 - box->bo_X1 + 1, height = box->bo_Y2 - box->bo_Y1 + 1;
  273.     SHORT status = EDITOR_STATUS_NORMAL;
  274.  
  275.     /* Init default template name */
  276.     if (default_name == TRUE)
  277.     {
  278.         build_default_template_name(tl, tp);
  279.     }
  280.  
  281.     /* Init default template data */
  282.     switch (TEMPLATE_GROUP(tp))
  283.     {
  284.     case TEMPLATE_GROUP_BORDER:
  285.         bd = &tp->tp_Data.tp_BorderData;
  286.         bd->bd_Type = BORDER_DATA_TYPE_BOX2_IN;
  287.         bd->bd_LeftEdge = box->bo_X1;
  288.         bd->bd_TopEdge = box->bo_Y1;
  289.         bd->bd_Width = width;
  290.         bd->bd_Height = height;
  291.  
  292.         /* Mark end of border data */
  293.         (bd + 1)->bd_Type = INTUISUP_DATA_END;
  294.         break;
  295.  
  296.     case TEMPLATE_GROUP_TEXT:
  297.         td = &tp->tp_Data.tp_TextData;
  298.         td->td_Type = TEXT_DATA_TYPE_TEXT;
  299.         td->td_Flags = 0;
  300.         td->td_LeftEdge = box->bo_X1;
  301.         td->td_TopEdge = box->bo_Y1;
  302.         if (!(td->td_TextAttr = open_template_font_by_attributes(tl,
  303.                                                                  DEFAULT_FONT_NAME, DEFAULT_FONT_YSIZE)))
  304.         {
  305.             status = EDITOR_ERROR_INVALID_FONT;
  306.         }
  307.         else
  308.         {
  309.             if ((status = duplicate_string("Text", &td->td_Text)) ==
  310.                 EDITOR_STATUS_NORMAL)
  311.             {
  312.                 /* Calc size of text for template box */
  313.                 box = &tp->tp_Box;
  314.                 box->bo_X2 = box->bo_X1 + IPrintText(pri, pwin, td->td_Text,
  315.                                                      td->td_LeftEdge, td->td_TopEdge, td->td_Type,
  316.                                                      TEXT_DATA_FLAG_NO_PRINT, td->td_TextAttr) - 1;
  317.                 box->bo_Y2 = box->bo_Y1 + td->td_TextAttr->ta_YSize - 1;
  318.             }
  319.  
  320.             /* Mark end of text data */
  321.             (td + 1)->td_Type = INTUISUP_DATA_END;
  322.         }
  323.         break;
  324.  
  325.     case TEMPLATE_GROUP_GADGET:
  326.         gd = &tp->tp_Data.tp_GadgetData;
  327.         gd->gd_Type = tp->tp_Type - FIRST_GADGET_TEMPLATE_TYPE + 1;
  328.         gd->gd_Flags = 0;
  329.         gd->gd_LeftEdge = box->bo_X1;
  330.         gd->gd_TopEdge = box->bo_Y1;
  331.         gd->gd_Width = width;
  332.         gd->gd_Height = height;
  333.         gd->gd_Text = NULL;
  334.         if (!(gd->gd_TextAttr = open_template_font_by_attributes(tl,
  335.                                                                  DEFAULT_FONT_NAME, DEFAULT_FONT_YSIZE)))
  336.         {
  337.             status = EDITOR_ERROR_INVALID_FONT;
  338.         }
  339.         else
  340.         {
  341.             switch (gd->gd_Type)
  342.             {
  343.             case GADGET_DATA_TYPE_BUTTON:
  344.                 status = duplicate_string("Button", &gd->gd_Text);
  345.                 break;
  346.  
  347.             case GADGET_DATA_TYPE_CHECK:
  348.                 gd->gd_SpecialData.gd_CheckData.gd_CheckSelected = 1;
  349.                 break;
  350.  
  351.             case GADGET_DATA_TYPE_MX:
  352.                 gd->gd_Flags |= GADGET_DATA_FLAG_TEXT_LEFT;
  353.                 gd->gd_SpecialData.gd_MXData.gd_MXSpacing = 1;
  354.                 gd->gd_SpecialData.gd_MXData.gd_MXActiveEntry = 0;
  355.                 if ((status = build_template_text_list(tp,
  356.                                                        &default_mx_text_array[0])) ==
  357.                     EDITOR_STATUS_NORMAL)
  358.                 {
  359.                     status = build_template_text_array(tp);
  360.                 }
  361.                 break;
  362.  
  363.             case GADGET_DATA_TYPE_STRING:
  364.                 gd->gd_SpecialData.gd_InputData.gd_InputLen = 10;
  365.                 gd->gd_SpecialData.gd_InputData.gd_InputActivateNext = 0;
  366.                 gd->gd_SpecialData.gd_InputData.gd_InputActivatePrev = 0;
  367.                 status = duplicate_string("String",
  368.                                           &gd->gd_SpecialData.gd_InputData.gd_InputDefault);
  369.                 break;
  370.  
  371.             case GADGET_DATA_TYPE_INTEGER:
  372.                 gd->gd_SpecialData.gd_InputData.gd_InputLen = 10;
  373.                 gd->gd_SpecialData.gd_InputData.gd_InputActivateNext = 0;
  374.                 gd->gd_SpecialData.gd_InputData.gd_InputActivatePrev = 0;
  375.                 gd->gd_SpecialData.gd_InputData.gd_InputDefault = (BYTE *) 123;
  376.                 break;
  377.  
  378.             case GADGET_DATA_TYPE_SLIDER:
  379.                 if (width / 2 < height)
  380.                 {
  381.                     gd->gd_Flags = GADGET_DATA_FLAG_ORIENTATION_VERT;
  382.                 }
  383.                 gd->gd_SpecialData.gd_SliderData.gd_SliderMin = 0;
  384.                 gd->gd_SpecialData.gd_SliderData.gd_SliderMax = 10;
  385.                 gd->gd_SpecialData.gd_SliderData.gd_SliderLevel = 5;
  386.                 break;
  387.  
  388.             case GADGET_DATA_TYPE_SCROLLER:
  389.                 if (width / 2 < height)
  390.                 {
  391.                     gd->gd_Flags = GADGET_DATA_FLAG_ORIENTATION_VERT;
  392.                 }
  393.                 gd->gd_SpecialData.gd_ScrollerData.gd_ScrollerVisible = 2;
  394.                 gd->gd_SpecialData.gd_ScrollerData.gd_ScrollerTotal = 10;
  395.                 gd->gd_SpecialData.gd_ScrollerData.gd_ScrollerTop = 5;
  396.                 break;
  397.  
  398.             case GADGET_DATA_TYPE_CYCLE:
  399.                 gd->gd_SpecialData.gd_CycleData.gd_CycleActive = 0;
  400.                 if ((status = build_template_text_list(tp,
  401.                                                        &default_cycle_text_array[0])) ==
  402.                     EDITOR_STATUS_NORMAL)
  403.                 {
  404.                     status = build_template_text_array(tp);
  405.                 }
  406.                 break;
  407.  
  408.             case GADGET_DATA_TYPE_COUNT:
  409.                 gd->gd_SpecialData.gd_CountData.gd_CountMin = 10;
  410.                 gd->gd_SpecialData.gd_CountData.gd_CountMax = 50;
  411.                 gd->gd_SpecialData.gd_CountData.gd_CountValue = 30;
  412.                 break;
  413.  
  414.             case GADGET_DATA_TYPE_LISTVIEW:
  415.                 gd->gd_Flags |= GADGET_DATA_FLAG_TEXT_ABOVE;
  416.                 gd->gd_SpecialData.gd_ListViewData.gd_ListViewSpacing = 0;
  417.                 gd->gd_SpecialData.gd_ListViewData.gd_ListViewTop = 0;
  418.                 gd->gd_SpecialData.gd_ListViewData.gd_ListViewList = &tp->tp_TextList;
  419.                 status = build_template_text_list(tp,
  420.                                                   &default_listview_text_array[0]);
  421.                 break;
  422.  
  423.             case GADGET_DATA_TYPE_PALETTE:
  424.                 if (width / 2 < height)
  425.                 {
  426.                     gd->gd_Flags |= GADGET_DATA_FLAG_PALETTE_INDICATOR_TOP;
  427.                 }
  428.                 gd->gd_Flags |= GADGET_DATA_FLAG_TEXT_ABOVE;
  429.                 gd->gd_SpecialData.gd_PaletteData.gd_PaletteDepth = 2;
  430.                 gd->gd_SpecialData.gd_PaletteData.gd_PaletteColorOffset = 0;
  431.                 gd->gd_SpecialData.gd_PaletteData.gd_PaletteActiveColor = 2;
  432.                 break;
  433.             }
  434.  
  435.             /* Mark end of gadget data */
  436.             (gd + 1)->gd_Type = INTUISUP_DATA_END;
  437.         }
  438.         break;
  439.     }
  440.     return (status);
  441. }
  442.  
  443.  /* Clone template and optional add it to template list */
  444.  
  445. struct Template *
  446. clone_template(struct TemplateList *tl, struct Template *old_tp,
  447.                BOOL full_clone)
  448. {
  449.     struct Template *new_tp;
  450.     SHORT status = EDITOR_STATUS_NORMAL;
  451.  
  452.     if (!(new_tp = AllocMem((LONG) sizeof(struct Template),
  453.                              (LONG) MEMF_PUBLIC | MEMF_CLEAR)))
  454.     {
  455.         status = EDITOR_ERROR_OUT_OF_MEM;
  456.     }
  457.     else
  458.     {
  459.  
  460.         /* Init template */
  461.         CopyMem((BYTE *) old_tp, (BYTE *) new_tp, (LONG) sizeof(struct Template));
  462.         new_tp->tp_Node.ln_Name = &new_tp->tp_TemplateName[0];
  463.         NewList(&new_tp->tp_TextList);
  464.         if (full_clone == FALSE)
  465.         {
  466.             CopyMem((BYTE *) & current_box, (BYTE *) & new_tp->tp_Box, (LONG)
  467.                     sizeof(struct Box));
  468.         }
  469.         if ((status = clone_template_data(tl, old_tp, new_tp)) !=
  470.             EDITOR_STATUS_NORMAL)
  471.         {
  472.             free_template(tl, new_tp);
  473.             new_tp = NULL;
  474.         }
  475.         else
  476.         {
  477.             if (full_clone == FALSE)
  478.             {
  479.  
  480.                 /* Add new template to list and refresh list view */
  481.                 add_template_to_list(tl, new_tp, TRUE);
  482.                 ISetGadgetAttributes(egl, EDITOR_GADGET_TEMPLATES, 0L, 0L,
  483.                                      USE_CURRENT_VALUE, USE_CURRENT_VALUE, &tl->tl_Templates);
  484.             }
  485.         }
  486.     }
  487.     show_error(status);
  488.     return (new_tp);
  489. }
  490.  
  491.  /* Clone template data */
  492.  
  493. STATIC SHORT
  494. clone_template_data(struct TemplateList * tl, struct Template * old_tp,
  495.                     struct Template * new_tp)
  496. {
  497.     struct BorderData *new_bd;
  498.     struct TextData *old_td, *new_td;
  499.     struct GadgetData *old_gd, *new_gd;
  500.     struct Box *box = &new_tp->tp_Box;
  501.     SHORT status = EDITOR_STATUS_NORMAL;
  502.  
  503.     /* Clear data pointers */
  504.     switch (TEMPLATE_GROUP(new_tp))
  505.     {
  506.     case TEMPLATE_GROUP_BORDER:
  507.         new_bd = &new_tp->tp_Data.tp_BorderData;
  508.         break;
  509.  
  510.     case TEMPLATE_GROUP_TEXT:
  511.         old_td = &old_tp->tp_Data.tp_TextData;
  512.         new_td = &new_tp->tp_Data.tp_TextData;
  513.         if (new_td->td_Type == TEXT_DATA_TYPE_TEXT)
  514.         {
  515.             new_td->td_Text = NULL;
  516.         }
  517.         new_td->td_TextAttr = NULL;
  518.         break;
  519.  
  520.     case TEMPLATE_GROUP_GADGET:
  521.         old_gd = &old_tp->tp_Data.tp_GadgetData;
  522.         new_gd = &new_tp->tp_Data.tp_GadgetData;
  523.         new_gd->gd_Text = NULL;
  524.         new_gd->gd_TextAttr = NULL;
  525.         switch (new_gd->gd_Type)
  526.         {
  527.         case GADGET_DATA_TYPE_BUTTON:
  528.         case GADGET_DATA_TYPE_CHECK:
  529.         case GADGET_DATA_TYPE_INTEGER:
  530.         case GADGET_DATA_TYPE_SLIDER:
  531.         case GADGET_DATA_TYPE_SCROLLER:
  532.         case GADGET_DATA_TYPE_COUNT:
  533.         case GADGET_DATA_TYPE_PALETTE:
  534.             break;
  535.  
  536.         case GADGET_DATA_TYPE_MX:
  537.             new_gd->gd_SpecialData.gd_MXData.gd_MXTextArray = NULL;
  538.             break;
  539.  
  540.         case GADGET_DATA_TYPE_CYCLE:
  541.             new_gd->gd_SpecialData.gd_CycleData.gd_CycleTextArray = NULL;
  542.             break;
  543.  
  544.         case GADGET_DATA_TYPE_STRING:
  545.             new_gd->gd_SpecialData.gd_InputData.gd_InputDefault = NULL;
  546.             break;
  547.  
  548.         case GADGET_DATA_TYPE_LISTVIEW:
  549.             new_gd->gd_SpecialData.gd_ListViewData.gd_ListViewList = &new_tp->tp_TextList;
  550.             break;
  551.         }
  552.         break;
  553.     }
  554.  
  555.     /* Allocate new data */
  556.     switch (TEMPLATE_GROUP(new_tp))
  557.     {
  558.     case TEMPLATE_GROUP_BORDER:
  559.         new_bd->bd_LeftEdge = box->bo_X1;
  560.         new_bd->bd_TopEdge = box->bo_Y1;
  561.         break;
  562.  
  563.     case TEMPLATE_GROUP_TEXT:
  564.         new_td->td_LeftEdge = box->bo_X1;
  565.         new_td->td_TopEdge = box->bo_Y1;
  566.         if (!(new_td->td_TextAttr = open_template_font_by_attributes(tl,
  567.                                                                      (BYTE *) old_td->td_TextAttr->ta_Name,
  568.                                                                      old_td->td_TextAttr->ta_YSize)))
  569.         {
  570.             status = EDITOR_ERROR_INVALID_FONT;
  571.         }
  572.         else
  573.         {
  574.             if (new_td->td_Type == TEXT_DATA_TYPE_TEXT)
  575.             {
  576.                 status = duplicate_string(old_td->td_Text, &new_td->td_Text);
  577.             }
  578.         }
  579.         break;
  580.  
  581.     case TEMPLATE_GROUP_GADGET:
  582.         new_gd->gd_LeftEdge = box->bo_X1;
  583.         new_gd->gd_TopEdge = box->bo_Y1;
  584.         if (!(new_gd->gd_TextAttr = open_template_font_by_attributes(tl,
  585.                                                                      (BYTE *) old_gd->gd_TextAttr->ta_Name,
  586.                                                                      old_gd->gd_TextAttr->ta_YSize)))
  587.         {
  588.             status = EDITOR_ERROR_INVALID_FONT;
  589.         }
  590.         else
  591.         {
  592.             if ((status = duplicate_string(old_gd->gd_Text,
  593.                                            &new_gd->gd_Text)) == EDITOR_STATUS_NORMAL)
  594.             {
  595.                 switch (new_gd->gd_Type)
  596.                 {
  597.                 case GADGET_DATA_TYPE_BUTTON:
  598.                 case GADGET_DATA_TYPE_CHECK:
  599.                 case GADGET_DATA_TYPE_INTEGER:
  600.                 case GADGET_DATA_TYPE_SLIDER:
  601.                 case GADGET_DATA_TYPE_SCROLLER:
  602.                 case GADGET_DATA_TYPE_COUNT:
  603.                 case GADGET_DATA_TYPE_PALETTE:
  604.                     break;
  605.  
  606.                 case GADGET_DATA_TYPE_MX:
  607.                 case GADGET_DATA_TYPE_CYCLE:
  608.                     if ((status = duplicate_text_list(old_tp, new_tp)) ==
  609.                         EDITOR_STATUS_NORMAL)
  610.                     {
  611.                         status = build_template_text_array(new_tp);
  612.                     }
  613.                     break;
  614.  
  615.                 case GADGET_DATA_TYPE_STRING:
  616.                     status = duplicate_string(old_gd->gd_SpecialData.gd_InputData.gd_InputDefault, &new_gd->gd_SpecialData.gd_InputData.gd_InputDefault);
  617.                     break;
  618.  
  619.                 case GADGET_DATA_TYPE_LISTVIEW:
  620.                     status = duplicate_text_list(old_tp, new_tp);
  621.                     break;
  622.                 }
  623.             }
  624.         }
  625.         break;
  626.     }
  627.     return (status);
  628. }
  629.  
  630.  /* Display template */
  631.  
  632. VOID
  633. display_template(struct Template * tp)
  634. {
  635.     struct TextData *td;
  636.     struct GadgetData *gd;
  637.     APTR gl;
  638.  
  639.     switch (TEMPLATE_GROUP(tp))
  640.     {
  641.     case TEMPLATE_GROUP_BORDER:
  642.         IDisplayBorders(pri, pwin, &tp->tp_Data.tp_BorderData, 0, 0);
  643.         break;
  644.  
  645.     case TEMPLATE_GROUP_TEXT:
  646.         td = &tp->tp_Data.tp_TextData;
  647.         IDisplayTexts(pri, pwin, td, 0, 0, NULL);
  648.         break;
  649.  
  650.     case TEMPLATE_GROUP_GADGET:
  651.         gd = &tp->tp_Data.tp_GadgetData;
  652.         if (!(gl = ICreateGadgets(pri, gd, 0, 0, NULL)))
  653.         {
  654.             show_error(EDITOR_ERROR_OUT_OF_MEM);
  655.         }
  656.         else
  657.         {
  658.             USHORT *dim = (USHORT *) (IGadgetAddress(gl, 0) + 1);
  659.  
  660.             /* Update template box with gadget size */
  661.             IDisplayGadgets(pwin, gl);
  662.             switch (gd->gd_Type)
  663.             {
  664.             case GADGET_DATA_TYPE_CHECK:
  665.             case GADGET_DATA_TYPE_MX:
  666.             case GADGET_DATA_TYPE_PALETTE:
  667.             case GADGET_DATA_TYPE_LISTVIEW:
  668.                 tp->tp_Box.bo_X2 = tp->tp_Box.bo_X1 + dim[0] - 1;
  669.                 tp->tp_Box.bo_Y2 = tp->tp_Box.bo_Y1 + dim[1] - 1;
  670.                 break;
  671.  
  672.             case GADGET_DATA_TYPE_STRING:
  673.             case GADGET_DATA_TYPE_INTEGER:
  674.                 tp->tp_Box.bo_X2 = tp->tp_Box.bo_X1 + dim[0] - 1;
  675.                 if (gd->gd_Flags & GADGET_DATA_FLAG_NO_BORDER)
  676.                 {
  677. /*    old!!   tp->tp_Box.bo_Y2 = tp->tp_Box.bo_Y1 + dim[1] - 1; */
  678.                     tp->tp_Box.bo_Y2 = tp->tp_Box.bo_Y1 + dim[1] - 1;
  679.                 }
  680.                 else
  681.                 {
  682. /*    old!!   tp->tp_Box.bo_Y2 = tp->tp_Box.bo_Y1 + dim[1] + 5; */
  683.                     tp->tp_Box.bo_Y2 = tp->tp_Box.bo_Y1 + dim[1] - 1;
  684.                 }
  685.                 break;
  686.             }
  687.             IRemoveGadgets(gl);
  688.             IFreeGadgets(gl);
  689.         }
  690.         break;
  691.     }
  692. }
  693.  
  694.  /* Refresh all templates */
  695.  
  696. VOID
  697. refresh_all_templates(VOID)
  698. {
  699.     struct TemplateList *tl = &template_list;
  700.     struct Template *tp;
  701.  
  702.     clear_project_window(tl->tl_Flags);
  703.     print_project_window_title();
  704.     if (editor_mode == EDITOR_MODE_USE)
  705.     {
  706.         IRefreshGadgets(use_gl);
  707.  
  708.         /* Refresh non gadget templates */
  709.         for (tp = get_head((struct List *) & tl->tl_Templates); tp;
  710.              tp = get_succ(&tp->tp_Node))
  711.         {
  712.             if (TEMPLATE_GROUP(tp) != TEMPLATE_GROUP_GADGET)
  713.             {
  714.                 display_template(tp);
  715.             }
  716.         }
  717.     }
  718.     else
  719.     {
  720.         for (tp = get_head((struct List *) & tl->tl_Templates); tp;
  721.              tp = get_succ(&tp->tp_Node))
  722.         {
  723.             display_template(tp);
  724.         }
  725.     }
  726. }
  727.  
  728.  /* Free template list */
  729.  
  730. VOID
  731. free_template_list(struct TemplateList *tl)
  732. {
  733.     struct Template *tp;
  734.     struct List *list = (struct List *) & tl->tl_Templates;
  735.  
  736.     free_font_list(tl);
  737.     while (tp = (struct Template *) RemHead(list))
  738.     {
  739.         switch (TEMPLATE_GROUP(tp))
  740.         {
  741.         case TEMPLATE_GROUP_BORDER:
  742.             tl->tl_BorderTemplates--;
  743.             break;
  744.  
  745.         case TEMPLATE_GROUP_TEXT:
  746.             tl->tl_TextTemplates--;
  747.             break;
  748.  
  749.         case TEMPLATE_GROUP_GADGET:
  750.             tl->tl_GadgetTemplates--;
  751.             break;
  752.         }
  753.         free_template(tl, tp);
  754.     }
  755.     tl->tl_Flags &= ~TEMPLATE_LIST_FLAG_CHANGED;
  756.     MWCheck();
  757. }
  758.  
  759.  /* Free template */
  760.  
  761. VOID
  762. free_template(struct TemplateList *tl, struct Template *tp)
  763. {
  764.     if (tl && tp)
  765.     {
  766.         free_template_data(tl, tp);
  767.         FreeMem(tp, (LONG) sizeof(struct Template));
  768.     }
  769. }
  770.  
  771.  /* Free template data */
  772.  
  773. VOID
  774. free_template_data(struct TemplateList *tl, struct Template *tp)
  775. {
  776.     struct TextData *td;
  777.     struct GadgetData *gd;
  778.  
  779.     switch (TEMPLATE_GROUP(tp))
  780.     {
  781.     case TEMPLATE_GROUP_BORDER:
  782.         break;
  783.  
  784.     case TEMPLATE_GROUP_TEXT:
  785.         td = &tp->tp_Data.tp_TextData;
  786.         close_template_font(tl, td->td_TextAttr);
  787.         if (td->td_Type == TEXT_DATA_TYPE_TEXT)
  788.         {
  789.             free(td->td_Text);
  790.         }
  791.         td->td_Text = NULL;
  792.         break;
  793.  
  794.     case TEMPLATE_GROUP_GADGET:
  795.         gd = &tp->tp_Data.tp_GadgetData;
  796.         close_template_font(tl, gd->gd_TextAttr);
  797.         free(gd->gd_Text);
  798.         gd->gd_Text = NULL;
  799.         switch (gd->gd_Type)
  800.         {
  801.         case GADGET_DATA_TYPE_BUTTON:
  802.         case GADGET_DATA_TYPE_CHECK:
  803.         case GADGET_DATA_TYPE_INTEGER:
  804.         case GADGET_DATA_TYPE_SLIDER:
  805.         case GADGET_DATA_TYPE_SCROLLER:
  806.         case GADGET_DATA_TYPE_COUNT:
  807.         case GADGET_DATA_TYPE_PALETTE:
  808.             break;
  809.  
  810.         case GADGET_DATA_TYPE_MX:
  811.         case GADGET_DATA_TYPE_CYCLE:
  812.             free_template_text_array(tp);
  813.         case GADGET_DATA_TYPE_LISTVIEW:
  814.             free_template_text_list(tp);
  815.             break;
  816.  
  817.         case GADGET_DATA_TYPE_STRING:
  818.             free(gd->gd_SpecialData.gd_InputData.gd_InputDefault);
  819.             break;
  820.         }
  821.         break;
  822.     }
  823. }
  824.  
  825.  /* Delete template */
  826.  
  827. VOID
  828. delete_template(struct Template *tp)
  829. {
  830.     struct TemplateList *tl = &template_list;
  831.     struct Template *succ_tp;
  832.     UBYTE group = TEMPLATE_GROUP(tp);
  833.  
  834.     /* Remove template from list, decrement counters and free template */
  835.     succ_tp = get_succ(&tp->tp_Node);
  836.     Remove(&tp->tp_Node);
  837.     switch (group)
  838.     {
  839.     case TEMPLATE_GROUP_BORDER:
  840.         tl->tl_BorderTemplates--;
  841.         break;
  842.  
  843.     case TEMPLATE_GROUP_TEXT:
  844.         tl->tl_TextTemplates--;
  845.         break;
  846.  
  847.     case TEMPLATE_GROUP_GADGET:
  848.         tl->tl_GadgetTemplates--;
  849.         break;
  850.     }
  851.     free_template(tl, tp);
  852.  
  853.     /* Update default template names and refresh template list */
  854.     for (tp = succ_tp; tp; tp = get_succ(&tp->tp_Node))
  855.     {
  856.         if (TEMPLATE_GROUP(tp) == group)
  857.         {
  858.             tp->tp_GroupEntryNum--;
  859.             if (tp->tp_Flags & TEMPLATE_FLAG_DEFAULT_NAME)
  860.             {
  861.                 build_default_template_name(tl, tp);
  862.             }
  863.         }
  864.     }
  865.     ISetGadgetAttributes(egl, EDITOR_GADGET_TEMPLATES, 0L, 0L,
  866.                          USE_CURRENT_VALUE, USE_CURRENT_VALUE, &tl->tl_Templates);
  867.     refresh_all_templates();
  868.     tl->tl_Flags |= TEMPLATE_LIST_FLAG_CHANGED;
  869. }
  870.